package customThreadPool;

import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
class TestDemo {
    public static void main(String[] args) throws Exception {

        MyThreadPoolInfo myThreadPoolInfo = new MyThreadPoolInfo(3);
        MyThreadPool myThreadPool = new MyThreadPool(myThreadPoolInfo);
        /*for (int i = 0; i < 5; i++) {
            myThreadPool.excuteProxyThread(() -> {

            });
        }*/
        Thread thread = new Thread();
        thread.start();

    }
}

class MyThreadPoolInfo implements Serializable {

    //初始化变量
    //容器
    private volatile ProxyRunable[] threadPoolArray;
    //标记位容器
    private volatile AtomicIntegerArray flagIntegerArray;
    //容器大小
    private int capcity;

    //构造方法
    public MyThreadPoolInfo(int capcity) throws Exception {

        if (capcity == 0) {
            throw new Exception("容量初始化失败！");
        }

        //初始化数据
        this.threadPoolArray = new ProxyRunable[capcity];
        this.flagIntegerArray = new AtomicIntegerArray(new int[capcity]);
        for (int i = 0; i < capcity; i++) {
            this.threadPoolArray[i] = new ProxyRunable();
        }
        this.capcity = capcity;
    }

    public ProxyRunable[] getThreadPoolArray() {
        return threadPoolArray;
    }

    public void setThreadPoolArray(ProxyRunable[] threadPoolArray) {
        this.threadPoolArray = threadPoolArray;
    }

    public AtomicIntegerArray getFlagIntegerArray() {
        return flagIntegerArray;
    }

    public void setFlagIntegerArray(AtomicIntegerArray flagIntegerArray) {
        this.flagIntegerArray = flagIntegerArray;
    }

    public int getCapcity() {
        return capcity;
    }

    public void setCapcity(int capcity) {
        this.capcity = capcity;
    }
}


@Slf4j
public class MyThreadPool {

    //解耦类
    MyThreadPoolInfo myThreadPoolInfo;

    volatile boolean lockFlag;

    //构造方法
    public MyThreadPool(MyThreadPoolInfo myThreadPoolInfo) {
        this.myThreadPoolInfo = myThreadPoolInfo;
        this.lockFlag = true;
    }


    //线程池执行操作
    //容器中获取线程对象
    public void excuteProxyThread(Runnable task) throws InterruptedException {
        //执行
        //判断容器是否还有线程对象

            while (true) {
                for (int i = 0; i < myThreadPoolInfo.getCapcity(); i++) {
                    //CAS操作
                    if (myThreadPoolInfo.getFlagIntegerArray().get(i) == 0) {
                        if (myThreadPoolInfo.getFlagIntegerArray().compareAndSet(i, 0, 1)) {
                            log.info(Thread.currentThread().getName() + myThreadPoolInfo.getThreadPoolArray()[i].toString() + "已被获取返回线程 ----in");
                            //如果有空闲的Thread,则执行
                            ProxyRunable item = myThreadPoolInfo.getThreadPoolArray()[i];

                            try {

                                System.out.println(item.isAlive());
                                //设置值并执行任务
                                    item.setTask(task, this.myThreadPoolInfo, this);
                                    item.start();

                                    return;


                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            //当池内线程连接用完后,自旋等待
           /* lockFlag = true;
                while (lockFlag){
                      Thread.sleep(1000);
                      log.info("wait.....");
                }*/
            }


    }
}

@Slf4j
class ProxyRunable extends Thread {

    private Runnable task;

    private MyThreadPool myThreadPool;

    MyThreadPoolInfo myThreadPoolInfo;

    public ProxyRunable() {

    }

    public void setTask(Runnable task, MyThreadPoolInfo myThreadPoolInfo, MyThreadPool myThreadPool) {
        this.task = task;
        this.myThreadPool = myThreadPool;
        this.myThreadPoolInfo = myThreadPoolInfo;
    }



    @Override
    public void run() {
        synchronized (this){
            try {
                //执行方法
                task.run();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //使用完毕,修改状态为空闲
                for (int i = 0; i < myThreadPoolInfo.getCapcity(); i++) {
                    if (myThreadPoolInfo.getThreadPoolArray()[i] == this) {
                        log.info(Thread.currentThread().getName() + myThreadPoolInfo.getThreadPoolArray()[i].toString() + "退回池中 ----back");
                        myThreadPoolInfo.getFlagIntegerArray().set(i, 0);
                        //myThreadPool.lockFlag = false;
                    }
                }
            }
        }

    }


}
